#include <clusnet/net/UdpClient.h>
#include <iostream>

int main(int argc, char* argv[])
{
    InitLogging();
    try
    {
        if (argc < 3)
        {
            LOG(ERROR) << "Usage: UdpClient_test <host> <port>";
            return 1;
        }

        boost::asio::io_context io_context;
        clusnet::net::UdpClientPtr client = std::make_shared<clusnet::net::UdpClient>(io_context, argv[1], argv[2]);
        client->setWriteCompleteCallback([](clusnet::net::UdpSessionPtr& session, clusnet::net::UdpDataPacketPtr const& data)
        {
            LOG(INFO) << "send to " << session->remoteEndpoint().address() << ":" << session->remoteEndpoint().port() << " " << data->dataLength() << " bytes";
        });
        client->setMessageCallback([](clusnet::net::UdpSessionPtr& session, clusnet::net::UdpUniqDataPacketPtr&& data)
        {
            LOG(INFO) << "recv from " << session->remoteEndpoint().address() << ":" << session->remoteEndpoint().port() << " " << data->dataLength() << " bytes. data: " << data->cdata();
        });
        client->safeStartReceive();

        std::thread t([&io_context] { io_context.run(); });

        std::string line;
        while (std::cin >> line)
        {
            clusnet::net::UdpDataPacketPtr data(new clusnet::net::UdpDataPacket);
            data->append(line.c_str(), line.length() + 1);
            client->safeAsyncWrite(data);
            if (line == "stop")
            {
                client->safeClose(); 
                break;
            }
        }
        t.join();
    }
    catch (std::exception& e)
    {
        LOG(ERROR) << "Exception: " << e.what();
    }

    return 0;
}
